package com.freely.ui.fragments;

import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.freely.R;
import com.freely.component.activity.FreelyApplication;
import com.freely.component.activity.TitleFragment;
import com.freely.data.entities.Group;
import com.freely.data.managerUtils.FreelySharedPreferences;
import com.freely.data.rxBus.RxBus;
import com.freely.data.services.FreelyServiceKt;
import com.freely.ui.listener.MapMarkerClickListener;
import com.freely.ui.service.MapService;
import com.freely.ui.viewModel.DetailViewModel;
import com.freely.ui.viewModel.GroupChatMapViewModel;
import com.google.android.material.bottomsheet.BottomSheetBehavior;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;

public class GroupChatMapFragment extends TitleFragment {

    private MapService mapService;
    private LocationManager locationManager;

    private MapView map;
    private long groupId;
    private boolean isFirst=true;
    private BaiduMap mBaiduMap;
    private double longtitude,latitude;
    private GroupChatMapViewModel groupChatMapViewModel;
    private View view;
    private BottomSheetBehavior bottomSheetBehavior;
    private static final String TAG = "GroupChatMapFragment";
    private long userId;
    private String address;
    private TextView tv_hint;

    public static GroupChatMapFragment newInstance() {
        return new GroupChatMapFragment();
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        mapService=new MapService(getActivity());
        View view = inflater.inflate(R.layout.fragment_group_chat_map, container,false);
        map = view.findViewById(R.id.map);
        tv_hint = view.findViewById(R.id.location_hint);
        this.view = view.findViewById(R.id.bottom_sheet);
        bottomSheetBehavior = BottomSheetBehavior.from(this.view);
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
        groupId=getArguments().getLong(Group.group_id);
        userId = FreelySharedPreferences.getInstance().getUserId();
        groupId = getArguments().getLong(Group.group_id);
        initMap();
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mapService = new MapService(getActivity());
        // TODO: Use the ViewModel
        Log.e(TAG, "onActivityCreated: " );
            return;
        }


    @Override
    public CharSequence getTitle() {
        return FreelyApplication.getContext().getString(R.string.group_location);
    }
    public void initMap(){
        groupChatMapViewModel = ViewModelProviders.of(this).get(GroupChatMapViewModel.class);
        map.removeViewAt(1);
        mBaiduMap = map.getMap();
        //普通地图 ,mBaiduMap是地图控制器对象
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        RxBus.Companion.getInstance().toObservable(FreelyServiceKt.MAP_LOCATION, BDLocation.class)
                .subscribe(bdLocation -> {
                    if (null != bdLocation ) {
                        if (bdLocation.getLatitude() != latitude || bdLocation.getLongitude() != longtitude || isFirst) {
                            isFirst = false;
                            latitude = bdLocation.getLatitude();
                            longtitude = bdLocation.getLongitude();
                            updateMap(bdLocation);
                        }
                    }
                });
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                mBaiduMap.hideInfoWindow();
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                return false;
            }
        });
        mBaiduMap.setMyLocationEnabled(true);
        // 设置定位图层的配置（定位模式，是否允许方向信息，用户自定义定位图标）
        // 开启定位图层
    }
    /*private BDAbstractLocationListener mListener = new BDAbstractLocationListener() {

        @Override
        public void onReceiveLocation(BDLocation location) {
           // groupChatMapViewModel.applyForUserLocation(location);
            //有变化才更新地图
            if (null != location && location.getLocType() != BDLocation.TypeServerError) {
                if (bdLocation.getLatitude() != latitude || bdLocation.getLongitude() != longtitude || isFirst) {
                    isFirst = false;
                    latitude = bdLocation.getLatitude();
                    longtitude = bdLocation.getLongitude();
                    updateMap(bdLocation);
                }
                StringBuffer sb = new StringBuffer(256);
                sb.append("time : ");
                /**
                 * 时间也可以使用systemClock.elapsedRealtime()方法 获取的是自从开机以来，每次回调的时间；
                 * location.getTime() 是指服务端出本次结果的时间，如果位置不发生变化，则时间不变

                sb.append(location.getTime());
                sb.append("\nlocType : ");// 定位类型
                sb.append(location.getLocType());
                sb.append("\nlocType description : ");// *****对应的定位类型说明*****
                sb.append(location.getLocTypeDescription());
                sb.append("\nlatitude : ");// 纬度
                sb.append(location.getLatitude());
                sb.append("\nlontitude : ");// 经度
                sb.append(location.getLongitude());
                sb.append("\nradius : ");// 半径
                sb.append(location.getRadius());
                sb.append("\nCountryCode : ");// 国家码
                sb.append(location.getCountryCode());
                sb.append("\nCountry : ");// 国家名称
                sb.append(location.getCountry());
                sb.append("\ncitycode : ");// 城市编码
                sb.append(location.getCityCode());
                sb.append("\ncity : ");// 城市
                sb.append(location.getCity());
                sb.append("\nDistrict : ");// 区
                sb.append(location.getDistrict());
                sb.append("\nStreet : ");// 街道
                sb.append(location.getStreet());
                sb.append("\naddr : ");// 地址信息
                sb.append(location.getAddrStr());
                sb.append("\nUserIndoorState: ");// *****返回用户室内外判断结果*****
                sb.append(location.getUserIndoorState());
                sb.append("\nDirection(not all devices have value): ");
                sb.append(location.getDirection());// 方向
                sb.append("\nlocationdescribe: ");
                sb.append(location.getLocationDescribe());// 位置语义化信息
                sb.append("\nPoi: ");// POI信息
                if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
                    for (int i = 0; i < location.getPoiList().size(); i++) {
                        Poi poi = (Poi) location.getPoiList().get(i);
                        sb.append(poi.getName() + ";");
                    }
                }
                if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                    sb.append("\nspeed : ");
                    sb.append(location.getSpeed());// 速度 单位：km/h
                    sb.append("\nsatellite : ");
                    sb.append(location.getSatelliteNumber());// 卫星数目
                    sb.append("\nheight : ");
                    sb.append(location.getAltitude());// 海拔高度 单位：米
                    sb.append("\ngps status : ");
                    sb.append(location.getGpsAccuracyStatus());// *****gps质量判断*****
                    sb.append("\ndescribe : ");
                    sb.append("gps定位成功");
                } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                    // 运营商信息
                    if (location.hasAltitude()) {// *****如果有海拔高度*****
                        sb.append("\nheight : ");
                        sb.append(location.getAltitude());// 单位：米
                    }
                    sb.append("\noperationers : ");// 运营商信息
                    sb.append(location.getOperators());
                    sb.append("\ndescribe : ");
                    sb.append("网络定位成功");
                } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                    sb.append("\ndescribe : ");
                    sb.append("离线定位成功，离线定位结果也是有效的");
                } else if (location.getLocType() == BDLocation.TypeServerError) {
                    sb.append("\ndescribe : ");
                    sb.append("服务端网络定位失败，可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com，会有人追查原因");
                } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                    sb.append("\ndescribe : ");
                    sb.append("网络不同导致定位失败，请检查网络是否通畅");
                } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                    sb.append("\ndescribe : ");
                    sb.append("无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机");
                }
                Log.e(TAG, "onReceiveLocation: "+sb );
            }else if(location.getLocType()==167){
                //无法进行网络定位就进行设备gps定位
                gpsLocation();
            }

        }
    };*/
    //在图上显示群成员的位置信息
    public void addGroupMember(){
        groupChatMapViewModel.loadMemberLocation(groupId);
        groupChatMapViewModel.getUserLocation().observe(this,RSUserLocation-> {
            List<OverlayOptions> options = new ArrayList<OverlayOptions>();
            Marker marker;
            if(null!=RSUserLocation){
                for (int i = 0; i < RSUserLocation.size(); i++) {
                    if (RSUserLocation.get(i).getUserId()==FreelySharedPreferences.getInstance().getUserId())
                        continue;
                    Log.e(TAG, "addGroupMember: "+RSUserLocation.get(i).getLocationLatitude()+"longtitude:"+RSUserLocation.get(i).getLocationLongitude());
                    LatLng point = new LatLng(RSUserLocation.get(i).getLocationLatitude(), RSUserLocation.get(i).getLocationLongitude());
                    BitmapDescriptor bitmap = BitmapDescriptorFactory
                            .fromResource(R.drawable.icon_location);
                    OverlayOptions option = new MarkerOptions()
                            .position(point)
                            .icon(bitmap);
                    marker = (Marker) mBaiduMap.addOverlay(option);
                    Bundle bundle = new Bundle();
                    //info必须实现序列化接口
                    bundle.putSerializable("info", RSUserLocation.get(i));
                    marker.setExtraInfo(bundle);
                }
            }
        });
        LatLng latLng = new LatLng(latitude,longtitude);
        mBaiduMap.setOnMarkerClickListener(new MapMarkerClickListener(view,getContext(),mBaiduMap,groupId,groupChatMapViewModel,latLng));
    }

    public void gpsLocation(){

        locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        boolean isGpsEnabled = locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
        String  locateType = locationManager.GPS_PROVIDER;
        @SuppressLint("MissingPermission") Location location = locationManager.getLastKnownLocation(locateType);
        if(location.getLatitude()!=latitude||location.getLongitude()!=longtitude||isFirst){
            isFirst=false;
            longtitude=location.getLongitude();
            latitude=location.getLatitude();
            Log.e(TAG, "gpsLocation: "+location.getAltitude()+"longtitule"+location.getLongitude());
            updateMap(location);
        }


    }
    //gps定位
    public void updateMap(Location location){
       // groupChatMapViewModel.applyForUserLocation(location);
        MyLocationData locData= new MyLocationData.Builder()
                .accuracy(0)
                .direction(100)
                .latitude(location.getLatitude())
                .longitude(location.getLongitude()).build();


        addGroupMember();
        mBaiduMap.setMyLocationEnabled(true);
        mBaiduMap.setMyLocationData(locData);

        if(isFirst){
            LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(10.0f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }



    }
    //百度网络定位
    public void updateMap(BDLocation location){
        tv_hint.setVisibility(View.GONE);
        MyLocationData locData= new MyLocationData.Builder()
                .accuracy(location.getRadius())
                .direction(100)
                .latitude(location.getLatitude())
                .longitude(location.getLongitude()).build();

        mBaiduMap.setMyLocationEnabled(true);
        addGroupMember();
        mBaiduMap.setMyLocationData(locData);
        LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
        MapStatus.Builder builder = new MapStatus.Builder();
        builder.target(ll).zoom(15.0f);
        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        mBaiduMap.setOnMyLocationClickListener(new BaiduMap.OnMyLocationClickListener() {
            @Override
            public boolean onMyLocationClick() {
                showLocation();
                return false;
            }
        });
    }

    //在地图上显示自己的位置信息
    public void showLocation(){

        View view = View.inflate(getContext(),R.layout.info_window,null);
        TextView name = view.findViewById(R.id.user_name_tv);
        ImageView iv = view.findViewById(R.id.icon_iv);
        TextView address = view.findViewById(R.id.address_tv);
        LatLng l = new LatLng(latitude,longtitude);
        setAddress(address);
        DetailViewModel detailViewModel = ViewModelProviders.of(this).get(DetailViewModel.class);

        detailViewModel.loadUser();

        detailViewModel.getUser().observe(this,user -> {

            name.setText(user.getUserName());
            byte[] headIconByte = Base64.decode(user.getUserImage(), Base64.DEFAULT);
            Glide.with(this)
                    .load(headIconByte)
                    .apply(RequestOptions.circleCropTransform())
                    .into(iv);
        });

        InfoWindow infoWindow = new InfoWindow(view,l,-5);
        mBaiduMap.showInfoWindow(infoWindow);
    }

    public void setAddress(TextView v){
        GeoCoder geoCoder=GeoCoder.newInstance();
        Log.e(TAG, "altitude: " +latitude+"longtitude"+longtitude);
        OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {
            public void onGetGeoCodeResult(GeoCodeResult result) {
                if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                    //没有检索到结果
                    return;
                }
                //获取地理编码结果
            }
            @Override

            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {

                if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                    v.setText("无法通过经纬度转换成地址");
                    return;
                }
                ReverseGeoCodeResult.AddressComponent addressComponent=result.getAddressDetail();

                String s  = addressComponent.province + addressComponent.city+addressComponent.district+addressComponent.street+addressComponent.streetNumber;

                Log.e(TAG, "onGetReverseGeoCodeResult: "+s );
                if (!s.equals(""))
                    v.setText(s);
                else
                    v.setText("该位置太过诡异，无法定位");

                geoCoder.destroy();
            }
        };
        LatLng latLng = new LatLng(latitude,longtitude);
        geoCoder.setOnGetGeoCodeResultListener(listener);
        geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latLng));
    }
}
